package com.tdd;

import static org.junit.Assert.assertEquals;

import java.math.BigDecimal;

import org.junit.Test;

public class CompositeOperationTest {
	OperationFactory factory = new OperationFactory();

	@Test(expected = NotADag.class)
	public void shouldNotAllowCirculaReferences() {
		CompositeOperation op = new CompositeOperation();
		op.add(op);
	}

	@Test
	public void demo() throws Exception {
		CompositeOperation op = new CompositeOperation();
		op.add(factory.findOperationNamed("+"));
		op.add(factory.findOperationNamed("*"));

		CompositeOperation opNested = new CompositeOperation();
		opNested.add(factory.findOperationNamed("sum"));
		opNested.add(factory.findOperationNamed("primeFactors"));
		op.add(opNested);

		HpStack stack = new HpStack();
		stack.push(new BigDecimal(3));
		stack.push(new BigDecimal(3));
		stack.push(new BigDecimal(3));
		stack.push(new BigDecimal(3));
		stack.push(new BigDecimal(4));
		stack.push(new BigDecimal(11));

		op.operate(stack);

		assertEquals(3, stack.pop());
		assertEquals(3, stack.pop());
		assertEquals(3, stack.pop());
		assertEquals(2, stack.pop());
	}

	@Test
	public void addThenMultiply() throws Exception {
		CompositeOperation op = new CompositeOperation();
		op.add(new Plus());
		op.add(new Multiply());

		HpStack stack = new HpStack();
		stack.push(new BigDecimal(3));
		stack.push(new BigDecimal(4));
		stack.push(new BigDecimal(11));

		op.operate(stack);

		assertEquals(45, stack.peek());
	}
}
